# -*- coding: utf-8 -*-
import json
import logging
import time
import requests
from traceback import format_exc
from selenium import webdriver
from scrapy.utils.project import get_project_settings

from abchina.util.rsa_util import RsaCrypter


class Launcher(object):
    # RSA公钥加载地址
    encrypt_key_url = 'https://e.abchina.com/qyjc/site/Security/EncryptKey?EncryptType=encrypt&InterfaceName=Security%2FEncryptKey'
    # AES密钥更新地址
    update_encrypt_url = 'https://e.abchina.com/qyjc/site/Security/UpdateEncrypt'
    # 验证码
    validate_code_url = 'https://e.abchina.com/qyjc/site/Account/ValidateCode?_=1552975002920'
    # 首页
    index_url = 'https://e.abchina.com/qyjc/group/index.html#/login'

    def __init__(self, timeout=60):
        settings = get_project_settings()
        self.max_login_retry = settings.get('MAX_LOGIN_RETRY', 2)
        self.accounts = settings.get('ACCOUNTS', [])
        self.timeout = timeout
        self.sec_key = ''
        self.sec_iv = ''
        self.rsa_modulus = ''
        self.rsa_exponent = ''
        self.cookies = dict()

    def init_cookie(self):
        """
        初始化cookie
        :return:
        """
        # 配置
        option = webdriver.ChromeOptions()
        # option.add_argument('--headless')
        option.add_argument('--no-sandbox')
        # 加载初始cookie
        browser = webdriver.Chrome(chrome_options=option)
        browser.set_window_size(1400, 700)
        browser.set_page_load_timeout(self.timeout)

        try:
            browser.get(self.index_url)
            time.sleep(6)
            selenium_cookies = browser.get_cookies()
            logging.info('--> cookies: %s' % selenium_cookies)
            # browser.close()

            # 重组cookie
            for cookie in selenium_cookies:
                self.cookies[cookie.get('name')] = cookie.get('value')
            # 校验cookie
            return self.__validate_cookie(self.cookies)
        except Exception as e:
            _ = e
            logging.error(format_exc())
            # browser.close()

    def __validate_cookie(self, cookies):
        """
        校验cookie
        :param cookies:
        :return:
        """
        if cookies and 'BIGipServerpool_ebiz_qyjc' in cookies \
                and cookies.get('GroupPurchaseSessionId'):
            return True
        return False

    def encrypt_key(self):
        """
        获取RSA公钥
        :return:
        """
        if not self.cookies:
            logging.error('no cookies error...')
            return

        r = requests.get(
            url=self.encrypt_key_url,
            headers={
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
                'Content-Type': 'application/json;charset=UTF-8',
            },
            cookies=self.cookies
        )
        if r and r.text:
            logging.info('EncryptKey API: %s' % r.text)
            rs = json.loads(r.text)
            if rs.get('Code', '') == 0 and 'Value' in rs:
                val = rs.get('Value', {})
                self.rsa_modulus = val.get('Modulus', '')
                self.rsa_exponent = val.get('Exponent', '')

    def update_encrypt(self):
        """
        更新ASE密钥
        :return:
        """
        if not self.rsa_modulus:
            logging.error('no rsa modulus error...')
            return
        if not self.rsa_exponent:
            logging.error('no rsa exponent error...')
            return
        if not self.cookies:
            logging.error('no cookies error...')
            return

        rsa = RsaCrypter(self.rsa_modulus, self.rsa_exponent)
        output_map = rsa.update_aes_encrypt()

        r = requests.post(
            url=self.update_encrypt_url,
            data=json.dumps({
                'Key': str(output_map.get('rsa_key'), encoding='utf-8')
            }),
            headers={
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36',
                'Content-Type': 'application/json;charset=UTF-8',
            },
            cookies=self.cookies
        )
        if r and r.text:
            logging.info('UpdateEncrypt API: %s' % r.text)
            rs = json.loads(r.text)
            if rs.get('Code', '') == 0:
                self.sec_key = output_map.get('aes_key')
                self.sec_iv = output_map.get('aes_iv')
                return True

        return False

    def launch(self, cookies=None):
        """
        加载入口
        :return:
        """
        if not cookies:
            self.init_cookie()
        else:
            self.cookies = cookies
        self.encrypt_key()
        self.update_encrypt()

    def refresh_encrypt(self, cookies):
        """
        加载入口
        :return:
        """
        self.cookies = cookies
        self.encrypt_key()
        self.update_encrypt()


if __name__ == '__main__':
    l = Launcher()
    l.launch()
